package com.nb.camerademo.adapter;

import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.ImageFormat;
import android.graphics.SurfaceTexture;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCaptureSession;
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CameraManager;
import android.hardware.camera2.CaptureFailure;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.CaptureResult;
import android.hardware.camera2.TotalCaptureResult;
import android.media.ImageReader;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Surface;
import android.view.TextureView;
import android.view.ViewGroup;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.core.app.ActivityCompat;
import androidx.recyclerview.widget.RecyclerView;

import com.nb.camerademo.ImageSaver;
import com.nb.camerademo.MainActivity;
import com.nb.camerademo.R;
import com.nb.camerademo.adapter.holder.CameraHolder;

import java.util.Arrays;
import java.util.List;

/**
 * @author Administrator on 2024-05-22.
 * <p>
 * 站在顶峰 看世界
 * 落到谷底 思人生
 */
public class CameraAdapter extends RecyclerView.Adapter<CameraHolder> {

    private Activity context;
    private CameraManager manager;
    private List<String> cameraList;

//    private CaptureRequest.Builder captureRequestBuilder1;

    public CameraAdapter(Activity context, CameraManager manager, List<String> cameraList) {
        this.context = context;
        this.manager = manager;
        this.cameraList = cameraList;
    }

    @NonNull
    @Override
    public CameraHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        return new CameraHolder(LayoutInflater.from(context).inflate(R.layout.item_camera, parent, false));
    }

    @Override
    public void onBindViewHolder(@NonNull CameraHolder holder, int position) {
        String cameraId = cameraList.get(position);

        final CameraCaptureSession[] cameraCaptureSession = new CameraCaptureSession[1];
        final CameraDevice[] cameraDevice = new CameraDevice[1];
        final ImageReader[] imageReader = new ImageReader[1];
        final CaptureRequest.Builder[] captureRequestBuilder1 = new CaptureRequest.Builder[1];
        holder.textureView.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() {
            @Override
            public void onSurfaceTextureAvailable(@NonNull SurfaceTexture surfaceTexture, int width, int height) {
                try {

                    imageReader[0] = ImageReader.newInstance(1920, 1080, ImageFormat.JPEG, 2);
                    imageReader[0].setOnImageAvailableListener(reader -> {
                        handler.post(new ImageSaver(reader.acquireNextImage()));
                        notifyItemChanged(holder.getAdapterPosition());
                    }, handler);


                    if (ActivityCompat.checkSelfPermission(context, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
                        ActivityCompat.requestPermissions(context, new String[]{Manifest.permission.CAMERA}, 200);
                        return;
                    }
                    manager.openCamera(cameraId, new CameraDevice.StateCallback() {
                        @Override
                        public void onOpened(@NonNull CameraDevice camera) {
                            try {
                                SurfaceTexture texture = holder.textureView.getSurfaceTexture();
                                if (texture == null) {
                                    return;
                                }
                                cameraDevice[0] = camera;
                                texture.setDefaultBufferSize(holder.textureView.getWidth(), holder.textureView.getHeight());
                                Surface surface = new Surface(texture);

                                captureRequestBuilder1[0] = camera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
                                captureRequestBuilder1[0].addTarget(surface);
                                camera.createCaptureSession(Arrays.asList(surface, imageReader[0].getSurface()), new CameraCaptureSession.StateCallback() {
                                    @Override
                                    public void onConfigured(@NonNull CameraCaptureSession session) {
                                        if (camera == null) {
                                            return;
                                        }
                                        cameraCaptureSession[0] = session;
                                        try {
                                            captureRequestBuilder1[0].set(CaptureRequest.CONTROL_MODE, CaptureRequest.CONTROL_MODE_AUTO);
                                            session.setRepeatingRequest(captureRequestBuilder1[0].build(), null, null);
                                        } catch (CameraAccessException e) {
                                            e.printStackTrace();
                                        }
                                    }

                                    @Override
                                    public void onConfigureFailed(@NonNull CameraCaptureSession session) {
                                        Log.v("MainActivity", "Failed to configure camera");
                                    }
                                }, null);
                            } catch (CameraAccessException e) {
                                e.printStackTrace();
                            }
                        }

                        @Override
                        public void onDisconnected(@NonNull CameraDevice camera) {
                            camera.close();
                        }

                        @Override
                        public void onError(@NonNull CameraDevice camera, int error) {
                            camera.close();
                        }
                    }, null);

                } catch (CameraAccessException e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onSurfaceTextureSizeChanged(@NonNull SurfaceTexture surface, int width, int height) {

            }

            @Override
            public boolean onSurfaceTextureDestroyed(@NonNull SurfaceTexture surface) {
                return false;
            }

            @Override
            public void onSurfaceTextureUpdated(@NonNull SurfaceTexture surface) {

            }
        });
        holder.tvPhoto.setOnClickListener(v -> {
            takePhoto(cameraDevice[0], cameraCaptureSession[0], imageReader[0], captureRequestBuilder1[0]);
        });
    }

    Handler handler = new Handler(Looper.getMainLooper()) {

    };

    /**
     * 拍照
     */
    private void takePhoto(final CameraDevice cameraDevice, final CameraCaptureSession cameraCaptureSession, ImageReader imageReader, CaptureRequest.Builder builder) {
        try {
            //创建拍照请求的Request
            CaptureRequest.Builder captureBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
            //设置拍照的画面
            captureBuilder.addTarget(imageReader.getSurface());
            //自动对焦
            captureBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
            //自动曝光
            captureBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);
            //获取手机方向
            int rotation = context.getWindowManager().getDefaultDisplay().getRotation();
            //根据设备方向计算设置照片的方向
//            captureBuilder.set(CaptureRequest.JPEG_ORIENTATION, ORIENTATIONS.get(rotation));
            //停止预览
            cameraCaptureSession.stopRepeating();
            //拍照
            cameraCaptureSession.capture(captureBuilder.build(), new CameraCaptureSession.CaptureCallback() {

                @Override
                public void onCaptureCompleted(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull TotalCaptureResult result) {
                    super.onCaptureCompleted(session, request, result);
                    try {
                        //自动对焦
                        captureBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CaptureRequest.CONTROL_AF_TRIGGER_CANCEL);
                        //重新打开预览
                        cameraCaptureSession.setRepeatingRequest(builder.build(), null, handler);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }

                @Override
                public void onCaptureFailed(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull CaptureFailure failure) {
                    super.onCaptureFailed(session, request, failure);
                    cameraCaptureSession.close();
                    cameraDevice.close();
                }

            }, handler);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    }

    @Override
    public int getItemCount() {
        return cameraList == null ? 0 : cameraList.size();
    }
}
